package com.luhuiguo.cms.client.presenter;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.gen2.table.event.client.HasPageLoadHandlers;
import com.google.gwt.gen2.table.event.client.HasRowSelectionHandlers;
import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.AppConstants;
import com.luhuiguo.cms.client.AppMessages;
import com.luhuiguo.cms.client.HandlerRegistrationAdapter;
import com.luhuiguo.cms.shared.event.AddArticleEvent;
import com.luhuiguo.cms.shared.event.EditArticleEvent;
import com.luhuiguo.cms.shared.event.FlashEvent;
import com.luhuiguo.cms.shared.model.ArticleModel;
import com.luhuiguo.cms.shared.rpc.RemoveArticles;
import com.luhuiguo.cms.shared.rpc.RemoveArticlesResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetPresenter;

@SuppressWarnings("deprecation")
public class ArticlesPresenter extends WidgetPresenter<ArticlesPresenter.Display> {

    public interface Display extends WidgetDisplay {

        HasClickHandlers getRefreshClick();

        HasClickHandlers getAddClick();

        HasClickHandlers getDeleteClick();

        HasPageLoadHandlers getDataTableLoad();

        HasRowSelectionHandlers getDataTableSelection();

        void addTableListener(TableListener listener);

        void removeTableListener(TableListener listener);

        ArticleModel getData(int row);

        Set<ArticleModel> getSelectedArticles();

        void setDeleteEnabled(boolean enabled);

        void reset();

        void reloadData();

        void setLoading(boolean loading);

    }

    private DispatcherAsync dispatcher;

    private ShowArticleTableListener tableListener = new ShowArticleTableListener();

    private AppConstants constants;

    private AppMessages messages;

    private Long channel;

    @Inject
    public ArticlesPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, AppConstants constants,
            AppMessages messages) {
        super(display, eventBus);
        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;
        GWT.log("ArticlesPresenter created");

    }

    @Override
    protected void onBind() {
        GWT.log("ArticlesPresenter onBind");
        registerHandler(display.getAddClick().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                GWT.log("[Add Article] button clicked");
                eventBus.fireEvent(new AddArticleEvent(channel));
            }

        }));

        registerHandler(display.getRefreshClick().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                display.reset();
                display.reloadData();
            }

        }));

        registerHandler(display.getDeleteClick().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                removeArticles();
            }

        }));

        registerHandler(new HandlerRegistrationAdapter(display.getDataTableSelection().addRowSelectionHandler(
                new RowSelectionHandler() {
                    public void onRowSelection(RowSelectionEvent event) {
                        if (event.getSelectedRows().size() == 0) {
                            display.setDeleteEnabled(false);
                        } else {
                            display.setDeleteEnabled(true);
                        }
                    }

                })));

        display.addTableListener(tableListener);

    }

    private final class ShowArticleTableListener implements TableListener {

        public void onCellClicked(SourcesTableEvents sender, int row, int cell) {

            display.setLoading(true);
            ArticleModel article = display.getData(row);

            eventBus.fireEvent(new EditArticleEvent(article));
        }

    }

    @Override
    protected void onRevealDisplay() {
        GWT.log("ArticlesPresenter onRevealDisplay");
        display.reloadData();
    }

    @Override
    protected void onUnbind() {
        GWT.log("ArticlesPresenter onUnbind");

    }

    public void revealDisplay(Long channel) {
        this.channel = channel;

        revealDisplay();
    }

    private void removeArticles() {
        display.setLoading(true);
        Set<ArticleModel> articles = display.getSelectedArticles();

        if (Window.confirm(messages.confirmDeleteArticles(articles.size()))) {

            List<Long> list = new ArrayList<Long>();
            for (ArticleModel a : articles) {
                list.add(a.getId());
            }

            dispatcher.execute(new RemoveArticles(list), new AsyncCallback<RemoveArticlesResult>() {

                public void onFailure(Throwable caught) {
                    display.setLoading(false);
                    eventBus.fireEvent(new FlashEvent(messages.deleteArticlesFailed(), -1));
                }

                public void onSuccess(RemoveArticlesResult result) {
                    display.setLoading(false);
                    display.reloadData();
                    eventBus.fireEvent(new FlashEvent(messages.articlesDeleted(result.get()), 2000));

                }

            });

        }

    }
}
